package com.office.office.wps;


import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.office.config.wps.*;
import com.office.core.CommonConfig;
import com.office.core.context.FileMetadata;
import com.office.office.wps.dto.FileConvertResult;
import com.office.office.wps.dto.OnnotifyMessage;
import com.office.office.wps.dto.TaskQueryResult;
import com.office.tools.OfficeResult;
import com.office.tools.RandomKey;
import com.office.tools.wps.PreviewMode;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.util.*;

/*
 * @BelongsProject: office
 * @BelongsPackage: com.office.office.wps
 * @Author: TongHui
 * @CreateTime: 2024-03-14 09:20
 * @Description: TODO
 * @Version: 1.0
 */
@Slf4j
public class WPSOfficeAPI extends AbstractWPSOfficeBase {

    public WPSOfficeAPI(CommonConfig configuration) {
        super(configuration);
    }


    /**
     * 查询任务详情
     */
    @Override
    public TaskQueryResult taskQuery(String taskId, String routeKey) {
        if (StringUtils.isEmpty(taskId) || StringUtils.isEmpty(routeKey)){
            throw new IllegalStateException("参数不能为空");
        }
        return sdkUtil.taskQuery(taskId, routeKey);
    }

    /**
     * 下载指定文件
     */
    @Override
    public byte[] fileDowload(String dowlaodId, String routeKey) {
        if (StringUtils.isEmpty(dowlaodId) || StringUtils.isEmpty(routeKey)){
            throw new IllegalStateException("参数不能为空");
        }
        return sdkUtil.fileDownload(dowlaodId,routeKey);
    }

    /**
     *  获取打开文件的连接
     * @param fileId  文件id
     * @param fileName  文件名称
     * @param _w_tokentype 是否传token ConstantsWPS.W_TOKENTYPE_YES/ConstantsWPS.W_TOKENTYPE_NO
     * @param params       自定义参数
     *  @return  link
     */
    public String openDocument(String fileId, String fileName, Integer _w_tokentype,Map<String,String> params) {
        //校验自定义参数
        verifyCustomParameter(params);
        if (_w_tokentype != ConstantsWPS.W_TOKENTYPE_YES && _w_tokentype != ConstantsWPS.W_TOKENTYPE_NO){
            throw new IllegalArgumentException("参数值不正确：_w_tokentype=1 or _w_tokentype=0");
        }

        OfficeResult editURl = this.sdkUtil.getEditURl(fileId, fileName, _w_tokentype, params);
        String data = (String) editURl.getData();
        JSONObject jsonObject = JSONUtil.toBean(data, JSONObject.class);
        return jsonObject.getStr("link");
    }

    /**
     *
     * @param fileId  文件id
     * @param fileName  文件名称
     * @param _w_tokentype 是否传token  ConstantsWPS.W_TOKENTYPE_YES/ConstantsWPS.W_TOKENTYPE_NO
     * @param previewMode 预览类型
     * @param wpsPreview 高清预览支持控制修订痕迹、评论是否显示等参数。 览参数wpsPreview=1111111从左到右依次代表：
     *                   第0位：格式修订：0不显示；1：显示
     *                   第1位：插入和删除：0不显示；1：显示
     *                   第2位：评论 0不显示；1：显示
     *                   第3位：以嵌入模式显示修订
     *                   第4位：以气泡模式显示修订
     *                   第5位：0不显示标记；1：显示标记
     *                   第6位：0最终状态；1：原始状态
     *       注：(第3、4位组合：01及11为批注框方式；10是嵌入方式
     *       00是批注框显示修订者)
     * @param params 自定义参数
     *  @return  link
     */
    public String openDocument(String fileId, String fileName, PreviewMode previewMode, Integer _w_tokentype, String  wpsPreview, Map<String,String> params) {
        //校验自定义参数
        verifyCustomParameter(params);

        if (_w_tokentype != ConstantsWPS.W_TOKENTYPE_YES && _w_tokentype != ConstantsWPS.W_TOKENTYPE_NO){
            throw new IllegalArgumentException("参数值不正确：_w_tokentype=1 or _w_tokentype=0");
        }

        OfficeResult previewURl = this.sdkUtil.getPreviewURl(fileId, fileName, previewMode, wpsPreview, _w_tokentype, params);
        String data = (String) previewURl.getData();
        JSONObject jsonObject = JSONUtil.toBean(data, JSONObject.class);
        return jsonObject.getStr("link");
    }


    /**
     * 同步
     * @param fileId      文件id
     * @param fileName    文件名称
     * @param password    密码
     * @param outformat   输出格式
     * @return 文件二进制
     * @throws Exception  抛出此异常
     */
    public byte[] convert(String fileId,String fileName,String password,String outformat) throws Exception {
        return convert(fileId,fileName,password,outformat,null,null,null,null);
    }

    /**
     * 异步
     * @param taskId 任务id。通过查询任务查看是否转换完成
     */
    public FileConvertResult convert(String taskId,String fileId,String fileName,String password,String outformat) throws Exception {
        return convert(taskId,fileId,fileName,password,outformat,null,null,null,null);
    }
    /**
     *
     * @param fileId      文件id
     * @param fileName    文件名称
     * @param password    密码
     * @param toPdf       转pdf的配置
     * @return 文件二进制
     * @throws Exception  抛出此异常
     */
    public byte[] convertToPdf(String fileId,String fileName,String password,ToPdf toPdf) throws Exception {
        return convert(fileId, fileName, password, "pdf",null,toPdf,null,null);
    }
    /**
     * 异步
     * @param taskId 任务id。通过查询任务查看是否转换完成
     */
    public FileConvertResult convertToPdf(String taskId,String fileId,String fileName,String password,ToPdf toPdf) throws Exception {
        return convert(taskId,fileId, fileName, password, "pdf",null,toPdf,null,null);
    }
    /**
     *
     * @param fileId      文件id
     * @param fileName    文件名称
     * @param password    密码
     * @param toPng       转png的配置
     * @return 文件二进制
     * @throws Exception  抛出此异常
     */
    public byte[] convertToPng(String fileId,String fileName,String password,ToPng toPng) throws Exception {
        return convert(fileId, fileName, password, "png",null,null,toPng,null);
    }
    /**
     * 异步
     * @param taskId 任务id。通过查询任务查看是否转换完成
     */
    public FileConvertResult convertToPng(String taskId,String fileId,String fileName,String password,ToPng toPng) throws Exception {
        return convert(taskId,fileId, fileName, password, "png",null,null,toPng,null);
    }
    /**
     *
     * @param fileId      文件id
     * @param fileName    文件名称
     * @param password    密码
     * @param outformat   输出格式
     * @param dpi         pdf 转图片 设置转换结果图片的dpi
     * @return 文件二进制
     * @throws Exception  抛出此异常
     */
    public byte[] pdfToImg(String fileId,String fileName,String password,String outformat,Integer dpi) throws Exception {
        return convert(fileId, fileName, password, outformat,dpi,null,null,null);
    }
    /**
     * 异步
     * @param taskId 任务id。通过查询任务查看是否转换完成
     */
    public FileConvertResult pdfToImg(String taskId,String fileId,String fileName,String password,String outformat,Integer dpi) throws Exception {
        return convert(taskId,fileId, fileName, password, outformat,dpi,null,null,null);
    }

    /**
     * 表格转换
     * @param fileId    文件id
     * @param fileName  文件名称
     * @param password   密码
     * @param outformat  输出格式
     * @param etPageZoom 表格配置
     * @return 文件二进制
     * @throws Exception   抛出此异常
     */
    public byte[] etConvert(String fileId,String fileName,String password,String outformat,EtPageZoom etPageZoom) throws Exception {
        return convert(fileId, fileName, password, outformat,null,null,null,etPageZoom);
    }
    /**
     * 异步
     * @param taskId 任务id。通过查询任务查看是否转换完成
     */
    public FileConvertResult etConvert(String taskId,String fileId,String fileName,String password,String outformat,EtPageZoom etPageZoom) throws Exception {
        return convert(taskId,fileId, fileName, password, outformat,null,null,null,etPageZoom);
    }

    /**
     * 同步转换
     * @param fileId      文件id
     * @param fileName    文件名称
     * @param password    密码
     * @param outformat   输出格式
     * @param dpi         pdf 转图片 设置转换结果图片的dpi
     * @param toPdf       转pdf的配置
     * @param toPng       转png的配置
     * @param etPageZoom  表格配置
     * @return 文件二进制
     * @throws Exception  抛出此异常
     */
    public byte[] convert(String fileId, String fileName, String password, String outformat, Integer dpi, ToPdf toPdf, ToPng toPng, EtPageZoom etPageZoom) throws Exception {
        ConvertInfo builder = new ConvertInfo.Builder()
                .taskId(RandomKey.SnowflakeId())
                .docUrl(getDownlaodUrl(fileId))
                .docFilename(fileName)
                .docPassword(wpsBaseInfo.getSecretKey(),password)
                .targetFileFormat(outformat)
                .etPageZoom(etPageZoom)
                .toPdf(toPdf)
                .toPng(toPng)
                .toImg(dpi)
                .builder();
        return this.sdkUtil.fileConvert_sync(builder);
    }

    /**
     * 异步转换
     * @param taskId      任务id
     * @param fileId      文件id
     * @param fileName    文件名称
     * @param password    密码
     * @param outformat   输出格式
     * @param dpi         pdf 转图片 设置转换结果图片的dpi
     * @param toPdf       转pdf的配置
     * @param toPng       转png的配置
     * @param etPageZoom  表格配置
     * @return 文件二进制
     * @throws Exception  抛出此异常
     */
    public FileConvertResult convert(String taskId, String fileId, String fileName, String password, String outformat, Integer dpi, ToPdf toPdf, ToPng toPng, EtPageZoom etPageZoom) throws Exception {
        ConvertInfo builder = new ConvertInfo.Builder()
                .taskId(taskId)
                .docUrl(getDownlaodUrl(fileId))
                .docFilename(fileName)
                .docPassword(wpsBaseInfo.getSecretKey(),password)
                .targetFileFormat(outformat)
                .etPageZoom(etPageZoom)
                .toPdf(toPdf)
                .toPng(toPng)
                .toImg(dpi)
                .builder();
        return this.sdkUtil.fileConvert_async(builder);
    }

    @Override
    public void handleOnnotifyMessage(OnnotifyMessage onnotifyMessage) {
        switch (onnotifyMessage.getCmd()){
            case ConstantsWPS.CMD_ONLINE:
                messageHandle.OnlineFile(onnotifyMessage.getBody());
                break;
            case ConstantsWPS.CMD_EXPORT:
                messageHandle.OperateRecordExport(onnotifyMessage.getBody());
                break;
            case ConstantsWPS.CMD_OPENPAGE:
                messageHandle.OpenPage(onnotifyMessage.getBody());
                break;
            case ConstantsWPS.CMD_QUIT:
                messageHandle.UserQuit(onnotifyMessage.getBody());

                break;
            case ConstantsWPS.CMD_JOIN:
                messageHandle.UserJoin(onnotifyMessage.getBody());
                break;
            case ConstantsWPS.CMD_DIRTY:
                messageHandle.FileDirty(onnotifyMessage.getBody());
                break;
            case ConstantsWPS.CMD_CLEAR:
                messageHandle.FileClear(onnotifyMessage.getBody());
                break;
            case ConstantsWPS.CMD_COMMENT:
                messageHandle.CommentAdd(onnotifyMessage.getBody());
                break;
            case ConstantsWPS.CMD_SERVEROPENFILE:
                messageHandle.ServerOpenFile(onnotifyMessage.getBody());
                break;
            default:
                throw new IllegalStateException("没有"+onnotifyMessage.getCmd()+"回调类型");
        }
    }
}
